<template>
    <div class="password-strength-meter">
      <div class="strength-meter">
        <div 
          v-for="n in 4" 
          :key="n" 
          class="strength-meter__bar"
          :class="getBarClass(n)"
        ></div>
      </div>
      <div class="strength-feedback">
        <span class="feedback-text">{{ strengthText }}</span>
        <ul v-if="feedback.suggestions.length" class="suggestions">
          <li v-for="(suggestion, index) in feedback.suggestions" :key="index">
            {{ suggestion }}
          </li>
        </ul>
      </div>
    </div>
  </template>
  
  <script>
  import { computed, ref, watch } from 'vue'
  
  export default {
    name: 'PasswordStrengthMeter',
    props: {
      password: {
        type: String,
        default: ''
      },
      // 可选的配置项
      options: {
        type: Object,
        default: () => ({
          minLength: 8,
          minScore: 2,
          showSuggestions: true
        })
      }
    },
    setup(props) {
      // 密码强度评分 (0-4)
      const score = ref(0)
      // 反馈信息
      const feedback = ref({
        warning: '',
        suggestions: []
      })
  
      // 强度等级文本
      const strengthText = computed(() => {
        const texts = [
          '非常弱',
          '弱',
          '一般',
          '强',
          '非常强'
        ]
        return texts[score.value]
      })
  
      // 密码强度计算
      const calculateStrength = (password) => {
        let newScore = 0
        const newFeedback = {
          warning: '',
          suggestions: []
        }
  
        // 空密码处理
        if (!password) {
          score.value = 0
          feedback.value = newFeedback
          return
        }
  
        // 长度检查
        if (password.length < props.options.minLength) {
          newFeedback.warning = '密码太短'
          newFeedback.suggestions.push(`密码长度至少需要${props.options.minLength}个字符`)
          score.value = 0
          feedback.value = newFeedback
          return
        }
  
        // 计分规则
        const hasLowerCase = /[a-z]/.test(password)
        const hasUpperCase = /[A-Z]/.test(password)
        const hasNumbers = /\d/.test(password)
        const hasSpecialChars = /[^a-zA-Z0-9]/.test(password)
        
        // 加分项
        if (hasLowerCase) newScore++
        if (hasUpperCase) newScore++
        if (hasNumbers) newScore++
        if (hasSpecialChars) newScore++
        
        // 长度奖励
        if (password.length > 12) newScore++
        
        // 减分项 - 连续字符或简单模式
        if (/(.)\1{2,}/.test(password)) newScore = Math.max(0, newScore - 1)
        if (/^(123|abc|password|qwerty)/i.test(password)) {
          newScore = 0
          newFeedback.warning = '密码太常见'
        }
  
        // 提供改进建议
        if (props.options.showSuggestions) {
          if (!hasLowerCase) {
            newFeedback.suggestions.push('添加小写字母')
          }
          if (!hasUpperCase) {
            newFeedback.suggestions.push('添加大写字母')
          }
          if (!hasNumbers) {
            newFeedback.suggestions.push('添加数字')
          }
          if (!hasSpecialChars) {
            newFeedback.suggestions.push('添加特殊字符 (!@#$%等)')
          }
        }
  
        score.value = Math.min(4, newScore) // 确保最大为4
        feedback.value = newFeedback
      }
  
      // 监听密码变化
      watch(() => props.password, (newVal) => {
        calculateStrength(newVal)
      }, { immediate: true })
  
      // 获取每个强度条的样式类
      const getBarClass = (n) => {
        return [
          { 'strength-meter__bar--active': n <= score.value },
          `strength-meter__bar--${score.value}`,
          { 'strength-meter__bar--error': score.value < props.options.minScore }
        ]
      }
  
      return {
        score,
        feedback,
        strengthText,
        getBarClass
      }
    }
  }
  </script>
  
  <style scoped>
  .password-strength-meter {
    margin-top: 8px;
    font-size: 14px;
  }
  
  .strength-meter {
    display: flex;
    gap: 4px;
    margin-bottom: 8px;
  }
  
  .strength-meter__bar {
    height: 4px;
    flex-grow: 1;
    background-color: #e0e0e0;
    border-radius: 2px;
    transition: all 0.3s ease;
  }
  
  .strength-meter__bar--active.strength-meter__bar--0 {
    background-color: #ff5252;
  }
  
  .strength-meter__bar--active.strength-meter__bar--1 {
    background-color: #ff9800;
  }
  
  .strength-meter__bar--active.strength-meter__bar--2 {
    background-color: #ffeb3b;
  }
  
  .strength-meter__bar--active.strength-meter__bar--3 {
    background-color: #4caf50;
  }
  
  .strength-meter__bar--active.strength-meter__bar--4 {
    background-color: #2e7d32;
  }
  
  .strength-meter__bar--error {
    animation: shake 0.5s ease-in-out;
  }
  
  .feedback-text {
    font-weight: bold;
  }
  
  .suggestions {
    margin: 4px 0 0 0;
    padding-left: 20px;
    color: #666;
    font-size: 12px;
  }
  
  @keyframes shake {
    0%, 100% { transform: translateX(0); }
    20%, 60% { transform: translateX(-2px); }
    40%, 80% { transform: translateX(2px); }
  }
  </style>